package CronJob

import (
	"Volta/Core/Container"
	"fmt"
	"reflect"
	"runtime/debug"
	"sync"
	"time"
)

func Execute() func(appNm string) {
	return func(appNm string) {
		instance, err := Container.App.Make(appNm)
		if err != nil {
			return
		}
		intervalTime := instance.ConValue.Elem().Field(0).Int()
		method := instance.ConValue.MethodByName(instance.Method)
		if !method.IsValid() {
			return
		}
		go jobControl(func() {
			defer endStack(appNm)
			method.Call([]reflect.Value{})
		},intervalTime)
	}
}

func jobControl(job func(),intervalTime int64)  {
	for {
		var syn sync.WaitGroup
		syn.Add(1)
		go work(&syn,job) //.定时任务每次周期都申请一个新的线程，以保证每次结束都能内存释放完全
		time.Sleep(time.Second * time.Duration(intervalTime))
		syn.Wait() //.当前任务线程执行结束才能进入下一个周期，否则一直阻塞
	}
}

func work(syn *sync.WaitGroup,job func()){
	job() //.执行定时任务
	syn.Add(-1)
}

func endStack(appNm string){
	if err := recover(); err != nil {
		//主体等信息+程序的堆栈信息
		msg := map[string]interface{}{
			"error":   err,                   		  //真正的错误信息
			"application": appNm,   				  //错误服务名
			"stack":   string(debug.Stack()), 		  //此刻程序的堆栈信息
		}
		fmt.Println(msg)
	}
}
